/*
 
This example reads standard from input and writes
to the default PCM device for 5 seconds of data.
 
*/
 
/* Use the newer ALSA API */
#define ALSA_PCM_NEW_HW_PARAMS_API
 
#include <alsa/asoundlib.h>
#include "comm.h"
 
int main() 
{
  long loops;
  int rc;
  int size;
  snd_pcm_t *handle;
  snd_pcm_hw_params_t *params;
  unsigned int val;
  int dir;
  snd_pcm_uframes_t frames;
  char *buffer;
 
  /* Open PCM device for playback. */
  rc = snd_pcm_open(&handle, "default",
                    SND_PCM_STREAM_PLAYBACK, 0);
  if (rc < 0)
  {
	printf("unable to open pcm device: %s\n",snd_strerror(rc));
	exit(1);
  }
  /* Allocate a hardware parameters object. */
  snd_pcm_hw_params_alloca(&params);
  /* Fill it in with default values. */
  snd_pcm_hw_params_any(handle, params);
  /* Set the desired hardware parameters. */
  /* Interleaved mode */
  snd_pcm_hw_params_set_access(handle, params,
                      SND_PCM_ACCESS_RW_INTERLEAVED);
  /* Signed 16-bit little-endian format */
  snd_pcm_hw_params_set_format(handle, params,
                              SND_PCM_FORMAT_S16_LE);
  /* Two channels (stereo) */
  snd_pcm_hw_params_set_channels(handle, params, 2);
  /* 44100 bits/second sampling rate (CD quality) */
  val = 44100;
  snd_pcm_hw_params_set_rate_near(handle, params,
                                  &val, &dir);
  /* Set period size to 32 frames. */
  frames = 1024;
  snd_pcm_hw_params_set_period_size_near(handle,
                              params, &frames, &dir);
  /* Write the parameters to the driver */
  rc = snd_pcm_hw_params(handle, params);
  if (rc < 0) {
    printf(
            "unable to set hw parameters: %s\n",
            snd_strerror(rc));
    exit(1);
  }
  /* Use a buffer large enough to hold one period */
  snd_pcm_hw_params_get_period_size(params, &frames,
                                    &dir);
  size = frames * 4; /* 2 bytes/sample, 2 channels */
  buffer = (char *) malloc(size);
  /* We want to loop for 5 seconds */
  snd_pcm_hw_params_get_period_time(params,&val, &dir);
  /* 5 seconds in microseconds divided by
   * period time */
  loops = 5000000 / val;
  int writeSize = 0;
  int cnt = 0;

  int soundFd = open("sound.wav", O_RDONLY);
    if (soundFd == -1) {
        printf("err: open %s failed\n", "sound.wav");
        return -1;
    }

  while (loops > 0) //循环录音 5 s  
  {
    loops--;
    rc = read(soundFd, buffer, size);
    if (rc == 0) //没有读取到数据 
    {
      printf( "end of file on input\n");
      break;
    } 
    else if (rc != size)//实际读取 的数据 小于 要读取的数据 
    {
      printf("short read: read %d bytes\n", rc);
    }
    
    writeSize += rc;
    printf("writeSize %d rc %d cnt %d\n", writeSize, rc, cnt++);
    hexdump(buffer, 16, "cnt %d", cnt);
	rc = snd_pcm_writei(handle, buffer, frames);//写入声卡  （放音） 
    if (rc == -EPIPE) 
    {
      /* EPIPE means underrun */
      printf( "underrun occurred\n");
      snd_pcm_prepare(handle);
    } else if (rc < 0) {
      printf("error from writei: %s\n",snd_strerror(rc));
    }  else if (rc != (int)frames) {
      printf("short write, write %d frames\n", rc);
    }
  }
  
  close(soundFd);

  snd_pcm_drain(handle);
  snd_pcm_close(handle);
  free(buffer);
  return 0;
}